package com.songlanyun.modules.pay.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.huifu.adapay.core.AdapayCore;
import com.huifu.adapay.core.util.AdapaySign;
import com.songlanyun.modules.pay.common.util.WxPayManager;
import com.songlanyun.pay.common.util.CalculateUtil;
import com.songlanyun.pay.common.util.AliPayManager;
import com.songlanyun.pay.common.util.HsqPayManager;
import com.songlanyun.pay.common.util.MapUtil;
import com.songlanyun.pay.common.util.SignUtil;
import com.songlanyun.pay.common.util.FileUtil;
import com.songlanyun.pay.common.util.AESUtil;
import com.songlanyun.pay.bean.PayBean;
import com.songlanyun.pay.bean.RefundModel;
import com.songlanyun.pay.bean.WithdrawBean;
import com.songlanyun.pay.common.api.ApiResult;
import com.songlanyun.pay.common.api.ResponseCode;
import com.songlanyun.pay.common.util.adap.AdaPayManager;
import com.songlanyun.pay.common.util.apakjp.AdaKjPayManager;
import com.songlanyun.pay.common.util.hsq.FastJsonUtil;
import com.songlanyun.pay.common.util.hsq.RSA2Encript;
import com.songlanyun.pay.common.util.hsq.RsaUtil;
import com.songlanyun.pay.common.util.hsq.StringUtil;
import com.songlanyun.pay.configure.*;
import com.songlanyun.pay.service.PayService;
import org.apache.commons.codec.digest.DigestUtils;
import org.dom4j.DocumentException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;

@Service("payService2")
public class PayServiceImpl implements PayService {
    private static final Logger log = LoggerFactory.getLogger(com.songlanyun.pay.service.impl.PayServiceImpl.class);
    @Autowired
    private WxPayConfig wxPayConfig;
    @Autowired
    private AliPayConfig aliPayConfig;
    @Autowired
    private AdaPayConfig adaPayConfig;
    @Autowired
    private HsqPayConfig hsqPayConfig;
    @Autowired
    private AdaKjPayConfig adaKjPayConfig;

    public PayServiceImpl() {
    }

    public ApiResult createPayOrder(PayBean payBean) throws Exception {
        int amountWxPay = CalculateUtil.multiply(Double.valueOf(payBean.getAmount()), 100.0, 2).intValue();
        Map<String, String> resultMap = new HashMap(16);
        switch (payBean.getPayType()) {
            case 11:
                String aliPayPCForm = AliPayManager.createPCOrder(payBean.getOrderNo(), String.valueOf(payBean.getAmount()), this.aliPayConfig);
                if (!StringUtils.isEmpty(aliPayPCForm)) {
                    resultMap.put("prePayOrderInfo", aliPayPCForm);
                    return ApiResult.success(resultMap);
                }
                break;
            case 12:
                String aliPayWapForm = AliPayManager.createWapOrder(payBean.getOrderNo(), String.valueOf(payBean.getAmount()), this.aliPayConfig);
                if (!StringUtils.isEmpty(aliPayWapForm)) {
                    resultMap.put("prePayOrderInfo", aliPayWapForm);
                    return ApiResult.success(resultMap);
                }
                break;
            case 13:
                String aliPayAppForm = AliPayManager.createAppOrder(payBean.getOrderNo(), String.valueOf(payBean.getAmount()), payBean.getDescription(), this.aliPayConfig);
                if (!StringUtils.isEmpty(aliPayAppForm)) {
                    resultMap.put("prePayOrderInfo", aliPayAppForm);
                    return ApiResult.success(resultMap);
                }
                break;
            case 14:
            case 15:
            case 16:
            case 17:
            case 18:
            case 19:
            case 20:
            case 26:
            case 27:
            case 28:
            case 29:
            case 30:
            case 32:
            case 33:
            case 34:
            case 35:
            case 36:
            case 37:
            case 38:
            case 39:
            case 40:
            case 45:
            case 46:
            case 47:
            case 48:
            case 49:
            case 50:
            default:
                return ApiResult.failure(ResponseCode.PAY_TYPE_ERROR);
            case 21:
                Map<String, String> wxPayNativeMap = WxPayManager.createNativeOrder(this.wxPayConfig, payBean.getOrderNo(), amountWxPay, payBean.getIp());
                if (wxPayNativeMap != null && Objects.equals(wxPayNativeMap.get("pre_pay_order_status"), this.wxPayConfig.getResponseSuccess())) {
                    resultMap.put("prePayOrderInfo", wxPayNativeMap.get("code_url"));
                    return ApiResult.success(resultMap);
                }
                break;
            case 22:
                if (StringUtils.isEmpty(payBean.getOpenId())) {
                    return ApiResult.failure(ResponseCode.PAY_SUBMIT_ERROR);
                }

                Map<String, String> wxPayJsAPIMap = WxPayManager.createJsAPIOrder(this.wxPayConfig, payBean.getOrderNo(), amountWxPay, payBean.getIp(), payBean.getOpenId());
                if (wxPayJsAPIMap != null && Objects.equals(wxPayJsAPIMap.get("pre_pay_order_status"), this.wxPayConfig.getResponseSuccess())) {
                    return ApiResult.success(wxPayJsAPIMap);
                }
                break;
            case 23:
                Map<String, String> wxPayH5Map = WxPayManager.createH5Order(this.wxPayConfig, payBean.getOrderNo(), amountWxPay, payBean.getIp());
                if (wxPayH5Map != null && Objects.equals(wxPayH5Map.get("pre_pay_order_status"), this.wxPayConfig.getResponseSuccess())) {
                    resultMap.put("prePayOrderInfo", wxPayH5Map.get("mweb_url"));
                    return ApiResult.success(resultMap);
                }
                break;
            case 24:
                Map<String, String> wxPayAppMap = WxPayManager.createAppOrder(this.wxPayConfig, payBean.getOrderNo(), amountWxPay, payBean.getIp(), payBean.getDescription());
                if (wxPayAppMap != null && Objects.equals(wxPayAppMap.get("pre_pay_order_status"), this.wxPayConfig.getResponseSuccess())) {
                    return ApiResult.success(wxPayAppMap);
                }
                break;
            case 25:
                if (StringUtils.isEmpty(payBean.getOpenId())) {
                    return ApiResult.failure(ResponseCode.PAY_SUBMIT_ERROR);
                }

                Map<String, String> wxPayMiniMap = WxPayManager.createMiniOrder(this.wxPayConfig, payBean.getOrderNo(), amountWxPay, payBean.getIp(), payBean.getOpenId(), payBean.getBody());
                if (wxPayMiniMap != null && Objects.equals(wxPayMiniMap.get("pre_pay_order_status"), this.wxPayConfig.getResponseSuccess())) {
                    return ApiResult.success(wxPayMiniMap);
                }
                break;
            case 31:
                Map<String, Object> result = AdaPayManager.createAdaAliPayAppOrder(payBean, this.adaPayConfig);
                if (ObjectUtil.isNotNull(result)) {
                    return ApiResult.success(result);
                }
                break;
            case 41:
            case 42:
            case 43:
            case 44:
                Map<String, Object> appOrder = HsqPayManager.createAppOrder(payBean, this.hsqPayConfig);
                if (ObjectUtil.isNotNull(appOrder)) {
                    return ApiResult.success(appOrder);
                }
                break;
            case 51:
                Map<String, Object> kjOrder = AdaKjPayManager.createAdaKjPayOrder(payBean, this.adaKjPayConfig);
                if (ObjectUtil.isNotNull(kjOrder)) {
                    return ApiResult.success(kjOrder);
                }
        }

        return ApiResult.failure(ResponseCode.PAY_SUBMIT_ERROR);
    }

    public ApiResult getPayResult(PayBean payBean) throws Exception {
        Map resultMap;
        switch (payBean.getPayType()) {
            case 11:
            case 12:
            case 13:
                resultMap = AliPayManager.getPayResult(this.aliPayConfig, payBean.getOrderNo());
                break;
            case 14:
            case 15:
            case 16:
            case 17:
            case 18:
            case 19:
            case 20:
            default:
                return ApiResult.failure(ResponseCode.PAY_TYPE_ERROR);
            case 21:
            case 22:
            case 23:
            case 24:
            case 25:
                resultMap = WxPayManager.getPayResult(this.wxPayConfig, payBean.getOrderNo());
        }

        return MapUtil.isEmpty(resultMap) ? ApiResult.failure(ResponseCode.PAY_STATUS_ERROR) : ApiResult.success(resultMap);
    }

    public String wxPayNotify(HttpServletRequest request, Function callBack) {
        String result = null;

        try {
            InputStream inputStream = request.getInputStream();
            String strXML = FileUtil.getStringFromStream(inputStream);
            Map<String, String> reqMap = MapUtil.xml2Map(strXML);
            if (MapUtil.isEmpty(reqMap)) {
                log.warn("request param is null");
                return this.wxFallReturnStr();
            } else if (!SignUtil.signValidate(reqMap, this.wxPayConfig.getKey(), this.wxPayConfig.getFieldSign())) {
                log.warn("wxPay sign is error");
                return this.wxFallReturnStr();
            } else if (!((String)reqMap.get("return_code")).equals(this.wxPayConfig.getResponseSuccess()) && !((String)reqMap.get("result_code")).equals(this.wxPayConfig.getResponseSuccess())) {
                return this.wxFallReturnStr();
            } else if (!callBack.apply(reqMap).toString().equals("success")) {
                return this.wxFallReturnStr();
            } else {
                result = this.wxReturnStr();
                return result;
            }
        } catch (IOException var7) {
            IOException e = var7;
            log.error("get request inputStream error", e);
            return this.wxPayConfig.getResponseFail();
        } catch (Exception var8) {
            Exception e = var8;
            log.error("resolve request param error", e);
            return this.wxPayConfig.getResponseFail();
        }
    }

    public String aliPayNotify(HttpServletRequest request, Function callBack) {
        Map<String, String> params = AliPayManager.getNotifyParams(request.getParameterMap());
        if (MapUtil.isEmpty(params)) {
            return this.aliPayConfig.getResponseFail();
        } else {
            try {
                if (!AlipaySignature.rsaCertCheckV1(params, this.aliPayConfig.getAlipayPublicCertPath(), this.aliPayConfig.getCharset(), this.aliPayConfig.getSignType())) {
                    return this.aliPayConfig.getResponseFail();
                }

                String orderNo = (String)params.get("out_trade_no");
                log.debug("支付宝回调,订单编号: {}", orderNo);
                if (!params.containsKey("refund_fee") || !params.containsKey("gmt_refund") && !params.containsKey("gmt_refund")) {
                    params.put("isRefund", "0");
                } else {
                    params.put("isRefund", "1");
                }

                if (!callBack.apply(params).toString().equals("success")) {
                    return this.aliPayConfig.getResponseFail();
                }
            } catch (AlipayApiException var5) {
                AlipayApiException e = var5;
                log.error("支付宝回调验证失败", e);
                return this.aliPayConfig.getResponseFail();
            } catch (Exception var6) {
                return this.aliPayConfig.getResponseFail();
            }

            return this.aliPayConfig.getResponseSuccess();
        }
    }

    public String adaPayNotify(HttpServletRequest request, Function callBack) {
        try {
            Map<String, String> params = AliPayManager.getNotifyParams(request.getParameterMap());
            String data = (String)params.get("data");
            String sign = (String)params.get("sign");
            String publicKey = AdapayCore.PUBLIC_KEY;
            log.info("验签请参：data={}sign={}");
            boolean checkSign = AdapaySign.verifySign(data, sign, publicKey);
            if (checkSign) {
                if (!callBack.apply(params).toString().equals("success")) {
                    return this.adaPayConfig.getResponseFail();
                }

                System.out.println("成功返回数据data:" + data);
                return this.adaPayConfig.getResponseSuccess();
            }
        } catch (Exception var8) {
            log.info("异步回调开始，参数，request={}");
        }

        return null;
    }

    public String hsqPayNotify(HttpServletRequest request, Function callBack) {
        log.info("慧收钱回调开始");

        try {
            Map<String, String> params = AliPayManager.getNotifyParams(request.getParameterMap());
            log.info("慧收钱回调参数，{}", params);
            String method = (String)params.get("method");
            String version = (String)params.get("version");
            String format = (String)params.get("format");
            String merchantNo = (String)params.get("merchantNo");
            String signType = (String)params.get("signType");
            String signContent = (String)params.get("signContent");
            String sign = (String)params.get("sign");
            String respResSign;
            if (signType.equals("CFCA")) {
                respResSign = RsaUtil.decryptByPubCerFile(signContent, this.hsqPayConfig.getHsqPublicKey());
                log.info("[回调] RSA公钥解密后内容：" + respResSign);
                respResSign = RsaUtil.base64Decode(respResSign);
                log.info("[回调] BASE64解密后内容：" + respResSign);
                Map resultMap = (Map) FastJsonUtil.convertJsonToObject(respResSign, Map.class);
                switch (resultMap.get("orderStatus").toString()) {
                    case "SUCCESS":
                        log.info("订单支付成功，成功金额为：" + resultMap.get("orderAmt") + "分");
                        if ("success".equals(callBack.apply(resultMap).toString())) {
                            return this.hsqPayConfig.getResponseSuccess();
                        }
                        break;
                    case "INIT":
                        log.info("订单初始化");
                        break;
                    case "PROCESSING":
                        log.info("处理中");
                        break;
                    default:
                        callBack.apply(resultMap);
                        log.error("订单支付失败：{}", resultMap);
                }
            } else {
                Map resultMap;
                if (signType.equals("RSA")) {
                    respResSign = RsaUtil.base64Decode(RsaUtil.decryptByPubCerFile(sign, this.hsqPayConfig.getHsqPublicKey()));
                    log.info("1.[回调]签文RSA BASE64解密后：" + respResSign);
                    String respSign = StringUtil.reqSingStr(method, version, format, merchantNo, signType, signContent, this.hsqPayConfig.getSignKey());
                    log.info("2.[响应] 固定格式拼接后：" + respSign);
                    respSign = RsaUtil.base64Encode(respSign);
                    log.info("3.[响应] BASE64加密内容" + respSign);
                    respSign = DigestUtils.md5Hex(respSign).toUpperCase();
                    log.info("4.[响应] md5加密结果:" + respSign);
                    if (respResSign.equals(respSign)) {
                        log.info("验签通过");
                        resultMap = (Map)FastJsonUtil.convertJsonToObject(signContent, Map.class);
                        switch (resultMap.get("orderStatus").toString()) {
                            case "SUCCESS":
                                log.info("订单支付成功，成功金额为：" + resultMap.get("orderAmt") + "分");
                                if ("success".equals(callBack.apply(resultMap).toString())) {
                                    return this.hsqPayConfig.getResponseSuccess();
                                }
                                break;
                            case "INIT":
                                log.info("订单初始化");
                                break;
                            case "PROCESSING":
                                log.info("处理中");
                                break;
                            default:
                                callBack.apply(resultMap);
                                log.error("订单支付失败：{}", resultMap);
                        }
                    } else {
                        log.error("验签失败，生成sign内容：" + respSign + ",与响应sign内容：" + respResSign + "不一致");
                    }
                } else if (signType.equals("RSA2")) {
                    respResSign = StringUtil.reqSingStr(method, version, format, merchantNo, signType, signContent, this.hsqPayConfig.getSignKey());
                    boolean verifyResult = RSA2Encript.verify(respResSign, sign, this.hsqPayConfig.getHsqPublicKey());
                    if (verifyResult) {
                        log.info("验签通过");
                        resultMap = (Map)FastJsonUtil.convertJsonToObject(signContent, Map.class);
                        switch (resultMap.get("orderStatus").toString()) {
                            case "SUCCESS":
                                log.info("订单支付成功，成功金额为：" + resultMap.get("orderAmt") + "分");
                                if ("success".equals(callBack.apply(resultMap).toString())) {
                                    return this.hsqPayConfig.getResponseSuccess();
                                }
                                break;
                            case "INIT":
                                log.info("订单初始化");
                                break;
                            case "PROCESSING":
                                log.info("处理中");
                                break;
                            default:
                                callBack.apply(resultMap);
                                log.error("订单支付失败：{}", resultMap);
                        }
                    }
                }
            }
        } catch (Exception var17) {
            Exception e = var17;
            log.error("异步回调失败：{}", e.getMessage());
        }

        return this.hsqPayConfig.getResponseFail();
    }

    public String aliPayReturnUrl(HttpServletRequest request) {
        Map<String, String> params = AliPayManager.getNotifyParams(request.getParameterMap());
        if (MapUtil.isEmpty(params)) {
            return "alipay_fail_url";
        } else {
            try {
                return !AlipaySignature.rsaCheckV1(params, this.aliPayConfig.getAlipayPublicKey(), this.aliPayConfig.getCharset(), this.aliPayConfig.getSignType()) ? "alipay_fail_url" : "alipay_success_url";
            } catch (AlipayApiException var4) {
                AlipayApiException e = var4;
                log.error("支付宝回调验证失败", e);
                return this.aliPayConfig.getResponseFail();
            }
        }
    }

    public String orderRefund(RefundModel refundModel, Function callBack) {
        if (refundModel.getPayType().toString().substring(0, 1).equals("1")) {
            return this.aliRefund(refundModel, callBack);
        } else if (refundModel.getPayType().toString().substring(0, 1).equals("2")) {
            return refundModel.getPayObject() == 0 ? this.wxRefund(refundModel, callBack) : this.wxRefundMini(refundModel, callBack);
        } else if (refundModel.getPayType().toString().substring(0, 1).equals("3")) {
            return this.adaRefund(refundModel, callBack);
        } else if (refundModel.getPayType() == 4) {
            return this.hsqRefund(refundModel, callBack);
        } else {
            return refundModel.getPayType() == 5 ? this.adaKjRefund(refundModel, callBack) : "";
        }
    }

    private String aliRefund(RefundModel refundModel, Function callBack) {
        return AliPayManager.aliRefund(this.aliPayConfig, refundModel, callBack);
    }

    private String adaRefund(RefundModel refundModel, Function callBack) {
        return AdaPayManager.adaRefund(this.adaPayConfig, refundModel, callBack);
    }

    private String hsqRefund(RefundModel refundModel, Function callBack) {
        return HsqPayManager.hsqRefund(this.hsqPayConfig, refundModel, callBack);
    }

    private String adaKjRefund(RefundModel refundModel, Function callBack) {
        return AdaKjPayManager.refund(this.adaKjPayConfig, refundModel, callBack);
    }

    private String wxRefund(RefundModel refundModel, Function callBack) {
        return WxPayManager.wxRefund(this.wxPayConfig, refundModel, callBack);
    }

    private String wxRefundMini(RefundModel refundModel, Function callBack) {
        return WxPayManager.wxRefundMini(this.wxPayConfig, refundModel, callBack);
    }

    public String callBackWxRefund(HttpServletRequest request, Function callBack) {
        try {
            InputStream inputStream = request.getInputStream();
            String strXML = FileUtil.getStringFromStream(inputStream);
            Map<String, String> reqMap = MapUtil.xml2Map(strXML);
            if (MapUtil.isEmpty(reqMap)) {
                log.warn("request param is null");
                return this.wxFallReturnStr();
            }

            if (!((String)reqMap.get("return_code")).equals(this.wxPayConfig.getResponseSuccess())) {
                log.error((String)reqMap.get("return_msg"));
                return this.wxFallReturnStr();
            }

            String req_info = (String)reqMap.get("req_info");
            String resultStr = AESUtil.decryptData(req_info, this.wxPayConfig.getKey());
            Map<String, String> aesMap = MapUtil.xml2Map(resultStr);
            String refund_status = (String)aesMap.get("refund_status");
            if (!refund_status.equals(this.wxPayConfig.getResponseSuccess())) {
                return this.wxFallReturnStr();
            }

            if (!callBack.apply(aesMap).toString().equals("success")) {
                return this.wxFallReturnStr();
            }

            return this.wxReturnStr();
        } catch (DocumentException var10) {
            DocumentException ex = var10;
            ex.printStackTrace();
        } catch (IOException var11) {
            IOException ex = var11;
            log.info("AES解密失败");
            ex.printStackTrace();
        } catch (Exception var12) {
            Exception ex = var12;
            log.info("AES解密失败");
            ex.printStackTrace();
        }

        return this.wxReturnStr();
    }

    public ApiResult entPay(WithdrawBean withdrawBean) throws Exception {
        Map<String, String> resultMap = new HashMap();
        switch (withdrawBean.getWithdrawType()) {
            case 11:
                resultMap = AliPayManager.entPay(withdrawBean.getIdentity(), withdrawBean.getAmount(), withdrawBean.getOutBizNo(), this.aliPayConfig);
                if (MapUtil.isEmpty((Map)resultMap)) {
                    return ApiResult.failure(ResponseCode.PAY_STATUS_ERROR);
                }

                String code = (String)((Map)resultMap).get("code");
                if (!"200".equals(code)) {
                    return ApiResult.failure((String)((Map)resultMap).get("subMsg"));
                }
                break;
            case 21:
                resultMap = WxPayManager.entPay(withdrawBean.getIdentity(), withdrawBean.getOutBizNo(), withdrawBean.getAmount(), this.wxPayConfig);
                if (MapUtil.isEmpty((Map)resultMap)) {
                    return ApiResult.failure(ResponseCode.PAY_STATUS_ERROR);
                }

                String resultCode = (String)((Map)resultMap).get("result_code");
                if (!"SUCCESS".equals(resultCode)) {
                    return ApiResult.failure((String)((Map)resultMap).get("err_code_des"));
                }
            case 31:
                break;
            default:
                return ApiResult.failure(ResponseCode.PARAMS_ERROR);
        }

        return ApiResult.success(resultMap);
    }

    private String wxReturnStr() {
        Map<String, String> resultMap = new HashMap(16);
        resultMap.put("return_code", "SUCCESS");
        resultMap.put("return_msg", "OK");
        String resultV = MapUtil.map2Xml(resultMap);
        return resultV;
    }

    private String wxFallReturnStr() {
        Map<String, String> resultMap = new HashMap(16);
        resultMap.put("return_code", "FAIL");
        resultMap.put("return_msg", "OK");
        String resultV = MapUtil.map2Xml(resultMap);
        return resultV;
    }
}
